package com.agh.szepczynski.magisterka.service.algorithms;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.agh.szepczynski.magisterka.service.beans.dm.Person;
import com.agh.szepczynski.magisterka.service.beans.dto.EventAlgorithm;
import com.agh.szepczynski.magisterka.service.events.AlgorithmState;

public class AlgorithmRoulette implements IContestAlghoritm {

	protected static final Log logger = LogFactory
			.getLog(AlgorithmRoulette.class);
	Random random = new Random();

	private List<Person> people;
	private int WINNERS_COUNT;

	private List<PersonMark> circleChart;
	private Float sumHeadingTo;

	Float currentAlgorithmSum = 0f;

	Person currentPerson = null;

	private List<PersonMark> createCircleChart() throws Exception {
		if (people == null || people.size() == 0) {
			throw new Exception("Empty people list");
		}

		List<PersonMark> circleChart = new ArrayList<PersonMark>();

		for (Person person : people) {
			Float mark = getPersonMark(person);
			PersonMark personMark = new PersonMark(person, mark);
			circleChart.add(personMark);
		}
		return circleChart;
	}

	@Override
	public AlgorithmState getAlgorithmState() {
		AlgorithmState algorithmState = new AlgorithmState();
		algorithmState.setCurrentPerson(currentPerson);
		algorithmState.setCurrentSum(currentAlgorithmSum);
		return algorithmState;
	}

	public List<PersonMark> getCircleChart() {
		return circleChart;
	}

	private Float getMarksSum() {
		Float sum = 0f;
		for (PersonMark personMark : circleChart) {
			sum += personMark.getMark();
		}
		return sum;
	}

	@Override
	public EventAlgorithm getName() {
		return EventAlgorithm.ALGORITHM_ROULETTE;
	}

	public List<Person> getPeople() {
		return people;
	}

	private Float getPersonMark(Person person) throws Exception {
		if(person.getAge()==null){
			throw new Exception("Age not defined for "+person.getId());
		}
		return new Float(person.getAge());
	}
	@Override
	public List<Person> getWinners() throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void init(List<Person> people, int winnersCount) throws Exception {
		this.WINNERS_COUNT = winnersCount;
		this.people = people;
		setCircleChart(createCircleChart());
		sumHeadingTo = random.nextFloat() * getMarksSum();
		System.out.println("Heading to sum "+sumHeadingTo);
	}

	@Override
	public boolean isEnded() {
		return currentAlgorithmSum >= sumHeadingTo;
	}

	@Override
	public void nextStep() {
		final Float MAX_STEP= sumHeadingTo/20f;
		final Float MIN_STEP= 1f;
		float step = random.nextFloat()*(MAX_STEP-MIN_STEP)+MIN_STEP;
		System.out.println("Stepping by: "+step);
		currentAlgorithmSum += step; //shoudl be good for the getmark function

		int i = 0;
		Float stepSum = 0f;
		while (stepSum < currentAlgorithmSum) {
			PersonMark personMark = circleChart.get(i);
			currentPerson = personMark.getPerson();
			stepSum += personMark.getMark();
			i++;
		}

	}

	public void setCircleChart(List<PersonMark> circleChart) {
		this.circleChart = circleChart;
	}

	public void setPeople(List<Person> people) {
		this.people = people;
	}

}
